C# |
您所在的位置:网站首页 › 监听tcp端口9000 创建socket › C# |
public socket (AddressFamily addressFamily,SocketType sockettype,ProtocolType protocolType)
(1) AddressFamily 用来指定socket解析地址的寻址方案,Inte.Network标示需要ip版本4的地址,Inte.NetworkV6需要ip版本6的地址; (2) SocketType 参数指定socket类型,Raw支持基础传输协议访问,Stream支持可靠,双向,基于连接的数据流; (3) ProtocolType 表示socket支持的网络协议,如常用的TCP和UDP协议。 3.3 定义主机对象 (1) IPEndPoint类原型: a) public IPEndPoint(IPAddress address,int port)参数address可以直接填写主机的IP,如"192.168.2.1"; b) public IPEndPoint(long address,int port)参数address整型int64如123456,参数port端口int32,如6655。 (2) 利用DNS服务器解析主机,使用Dns.Resolve方法原型: public static IPHostEntry Resolve(string hostname) 参数:待解析的主机名称,返回IPHostEntry类值,IPHostEntry为Inte.Net主机地址信息提供容器,该容器提供存有IP地址列表,主机名称等。 (3) Dns.GetHostByName获取本地主机名称原型: public static IPHostEntry GetHostByName(string hostname) (4) GetHostByAddress原型: a) public static IPHostEntry GetHostByAddress(IPAddress address)参数:IP地址。 b) public static IPHostEntry GetHostByAddress(string address) 参数:IP地址格式化字符串。 3.4 端口绑定和监听同步套接字服务器主机的绑定和端口监听,Socket类的Bind(绑定主机),Listen(监听端口),Accept(接收客户端的连接请求)。 (1) Bind原型: public void Bind(EndPoint LocalEP) 参数为主机对象 IPEndPoint (2) Listen原型: public void Listen(int backlog)参数整型数值,挂起队列最大值 (3) accept原型: public socket accept()返回为套接字对象 3.5 socket的发送和接收方法 (1) 发送数据a)socket类的send方法 原型一: public int Send(byte[] buffer)参数:待发送的字节数组; 原型二: public int Send(byte[],SocketFlags) SocketFlags成员列表: DontRoute不使用路由表发送, MaxIOVectorLength为发送和接收数据的wsabuf结构数量提供标准值, None 不对次调用使用标志, OutOfBand消息的部分发送或接收, Partial消息的部分发送或接收, Peek查看传入的消息。 原型三: public int Send(byte[],int,SocketFlags) 参数二要发送的字节数 原型四: public int Send(byte[],int,int,SocketFlags) 参数二为Byte[]中开始发送的位置 b) NetWordStream类的Write方法 原型: public override void write(byte[] buffer,int offset,int size) 参数分别为:字节数组,开始字节位置,总字节数。 (2) 接收数据a) Socket类Receive方法 原型一: public int Receive(byte[] buffer) 原型二:public int Receive(byte[],SocketFlags)原型三:public int Receive(byte[],int,SocketFlags)原型四: public int Receive(byte[],int,int,SocketFlags)Socket类Receive方法的相关参数可参看Socket类Send方法中的参数。 b) NetworkStream类的Read方法 public override int Read(int byte[] buffer,int offset,int size)参数可参看NetworkStream类的Write方法。 四、TCP传输协议的同步实现 4.1 服务器端编程的步骤:(1) 创建套接字; (2) 绑定套接字到一个IP地址和一个端口上(bind()); (3)将套接字设置为监听模式等待连接请求(listen()); (4)请求到来后,接受连接请求,返回一个新的对应于此次连接的套接字(accept()); (5)用返回的套接字和客户端进行通信(send()/recv()); (6)返回,等待另一连接请求; (7)关闭套接字。 服务器端代码: using System; using System.Net; using System.Net.Sockets; using System.Collections.Generic; using System.Text; namespace net { class Program { static void Main(string[] args) { //定义接收数据长度变量 int recv; //定义接收数据的缓存 byte[] data = new byte[1024]; //定义侦听端口 IPEndPoint ipEnd = new IPEndPoint(IPAddress.Any, 5566); //定义套接字类型 Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //连接 socket.Bind(ipEnd); //开始侦听 socket.Listen(10); //控制台输出侦听状态 Console.Write("Waiting for a client"); //一旦接受连接,创建一个客户端 Socket client = socket.Accept(); //获取客户端的IP和端口 IPEndPoint ipEndClient = (IPEndPoint)client.RemoteEndPoint; //输出客户端的IP和端口 Console.Write("Connect with {0} at port {1}", ipEndClient.Address, ipEndClient.Port); //定义待发送字符 string welcome = "Welcome to my server"; //数据类型转换 data = Encoding.ASCII.GetBytes(welcome); //发送 client.Send(data, data.Length, SocketFlags.None); while (true) { //对data清零 data = new byte[1024]; //获取收到的数据的长度 recv = client.Receive(data); //如果收到的数据长度为0,则退出 if (recv == 0) break; //输出接收到的数据 Console.Write(Encoding.ASCII.GetString(data, 0, recv)); //将接收到的数据再发送出去 client.Send(data, recv, SocketFlags.None); } Console.Write("Disconnect form{0}", ipEndClient.Address); client.Close(); socket.Close(); } } }4.2 客户端编程的步骤:(1) 创建套接字; (2) 向服务器发出连接请求(connect()); (3) 和服务器端进行通信(send()/recv()); (4) 关闭套接字。 客户端代码: using System; using System.Net; using System.Net.Sockets; using System.Collections.Generic; using System.Text; namespace client { class Program { static void Main(string[] args) { //定义发送数据缓存 byte[] data = new byte[1024]; //定义字符串,用于控制台输出或输入 string input, stringData; //定义主机的IP及端口 IPAddress ip = IPAddress.Parse("127.0.0.1"); IPEndPoint ipEnd = new IPEndPoint(ip, 5566); //定义套接字类型 Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //尝试连接 try { socket.Connect(ipEnd); } //异常处理 catch (SocketException e) { Console.Write("Fail to connect server"); Console.Write(e.ToString()); return; } //定义接收数据的长度 int recv = socket.Receive(data); //将接收的数据转换成字符串 stringData = Encoding.ASCII.GetString(data, 0, recv); //控制台输出接收到的数据 Console.Write(stringData); //定义从键盘接收到的字符串 input = Console.ReadLine(); //将从键盘获取的字符串转换成整型数据并存储在数组中 data = Encoding.ASCII.GetBytes(input); //发送该数组 socket.Send(data, data.Length, SocketFlags.None); while (true) { // //如果字符串是"exit",退出while循环 if (input == "exit") { break; } //对data清零 data = new byte[1024]; //定义接收到的数据的长度 recv = socket.Receive(data); //将接收到的数据转换为字符串 stringData = Encoding.ASCII.GetString(data, 0, recv); //控制台输出字符串 Console.Write(stringData); //发送收到的数据 socket.Send(data, recv, 0); } Console.Write("disconnect from server"); socket.Shutdown(SocketShutdown.Both); socket.Close(); } } }上述代码实现了,当连接建立之后,客户端向服务器端发送键盘输入的字符,服务器端收到字符后,显示在控制台并发送给客户端,客户端收到字符后,显示在控制台并再次发送给服务器端,如此循环。 五、实验结果先后运行服务器端程序和客户端程序,控制台界面如下:
图1 服务器端控制台 当连接建立后,服务器端控制台显示等待客户端的状态"Waiting for a client",并打印出连接信息。
图2 客户端控制台 当连接建立后,客户端收到来自服务器端发送的字符串"Welcome to my server"。 之后,客户端通过键盘发送数据,二者循环接收并发送,控制台分别如下: 图3 服务器控制台 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |